package com.fengqianrun.bootframework.config.aspect;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.fengqianrun.bootframework.config.aspect.annotation.LogAno;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
@Slf4j
public class LogAspect {

    /**
     * 操作日志 人，时间，ip，方法名，参数，返回值，执行时间
     * @param point
     * @return
     * @throws Throwable
     */
    @Around("execution(* com.fengqianrun.bootframework.controller..*(..))")
    public Object Around(ProceedingJoinPoint point) throws Throwable {
        // 获取request
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        String requestUrl = request.getRequestURL().toString();
        long startTime = System.currentTimeMillis();
        Object result = null;
        try {
            // 执行方法
            MethodSignature method = (MethodSignature) point.getSignature();
            LogAno logAno = method.getMethod().getDeclaredAnnotation(LogAno.class);
            result = point.proceed();
            if(ObjectUtil.isEmpty(logAno)){
                return result;
            }
            method.getMethod().getName();
            String name = logAno.name();
            Object[] args = point.getArgs();
            long endTime = System.currentTimeMillis();
            log.info("Request url: {}, params: {}, response: {}, cost: {} ms",
                    requestUrl, point.getArgs(), JSONUtil.toJsonStr(result), endTime-startTime);
        }catch (Exception e){
            log.error("Request url: {} failed...", requestUrl, e);
            throw e;
        }
        return result;
    }

}
